Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

style: address flake8 e402 warning in the codebase #3354

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

Sharansrj567
Copy link
Contributor

Initiated the resolution of Flake8 E402 warnings throughout the codebase by moving imports to the top of the files. However, encountered a scenario where certain module imports are conditional based on the platform (Windows or non-Windows).

Due to platform-dependent imports, moving them to the top would break the conditional logic. To maintain code integrity and adhere to PEP 8, introduced a pattern where platform-specific imports are encapsulated within functions, ensuring they are called when needed.

Following this adjustment, successfully resolved E402 warnings associated with conditional imports.

Subsequently, addressed E302 and E305 warnings by adding appropriate blank lines after import statements and before class/function definitions. This conforms to PEP 8 conventions for improved code readability.

The codebase now aligns with coding standards, maintains platform-specific imports efficiently, and has an enhanced overall structure.

Related to: issue #1522

@github-actions github-actions bot added GUI wxGUI related raster Related to raster data processing Python Related code is in Python libraries module docs labels Jan 11, 2024
@wenzeslaus wenzeslaus self-assigned this Jan 11, 2024
Comment on lines 22 to 23
if not os.getenv("GISBASE"):
sys.exit("GISBASE not defined")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change of moving the check under has the sys.path.insert calls won't have the expected outcome. Starting at line 24, that environment variable is used. Having the check after having finished using it isn't equivalent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for pointing that out. I've reconsidered the placement of the check and modified the code to ensure its effectiveness. I will push the changes to update the PR.

Comment on lines 26 to 35

def import_grass_libs():
import grass.lib.gis as libgis
libgis.G_gisinit("")
import grass.lib.raster as libraster
import grass.lib.rowio as librowio
return libgis, libraster, librowio


libgis, libraster, librowio = import_grass_libs()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using that pattern might complicate static analysis, as the imports aren't directly visible (it is a kind of lazy loading, but the call to that function is made during a parsing of the file for an import for example).

Does the lib raster and lib rowio import successfully and work correctly if libgis.G_gisinit("") isn't called strictly before, but underneath?

This pattern seems to be on multiple files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for highlighting the concern. I agree, and to address it, I've modified the code on all the changed files to keep the imports at the module level for direct visibility while maintaining the lazy loading pattern. I will update the PR with these changes

Copy link
Member

@echoix echoix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've written as a file-level comment which files I think have non-controversial changes. If this PR gets too stalled, at least the changes to these files could be integrated without too much problems.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file I'm ok with.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file I'm ok with.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file I'm ok with.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is most probably fine.

Comment on lines 27 to -29
0, os.path.abspath(os.path.join(os.environ["GISBASE"], "etc", "python", "grass"))
)

from grass.script import core

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might not behave successfully. Is there a way to know if it imports well, and not only wrapped inside a grass --exec python. I've hit some long import chains that needed everything already up and running in order to have something similar working. To confirm.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran GRASS GIS, accessed the interactive terminal, entered the Python shell within that environment, and executed the import statement without encountering any errors.

Copy link
Member

@echoix echoix Feb 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, I see that this file is for generating docs (sphinx). Does someone know how to trigger it to check it? I know that the docs are built daily on an OSGeo server

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file I'm ok with.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file I'm ok with.

from core.debug import Debug
from core.globalvar import SCT_EXT

from grass.script import core as grass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if that's not from this PR, this doesn't sound right, and quite ambiguous (the alias's name)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've noticed that across our codebase, there is a consistent use of the alias grass for the core module. Given that this pattern is present in around 51 files, it might be worth discussing whether we want to maintain this convention or consider a more descriptive alias.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure this was introduced when transitioning form a single-file package called grass(.script?) to multiple files (modules). Functions in original grass or something like that were moved core and grass or grass.script got new functions. grass.script.core then became what grass once was. These imports were the least intrusive change, so it was implemented that way. This was in the pre-v7-times on Subversion trunk, but it was propagated sufficiently through the code base at the time of v7 release that it became a standard for v7. We came up with grass.script as gs as a better practice, but didn't go back (yet) to replace all occurrences of core as grass.

@neteler neteler added this to the 8.4.0 milestone Jan 14, 2024
@github-actions github-actions bot removed the docs label Jan 16, 2024
Comment on lines 35 to +37
from gui_core.wrap import Button, StaticText

set_gui_path()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has there been a careful analysis of what is needed for gui_core.wrap import to be successful, and what does set_gui_path provide?

@@ -18,8 +18,16 @@

import socket
import grass.script as grass
import numpy as Numeric
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it was there before, but probably a new PR for this, but it is almost an universal convention across all Python code that numpy is imported as np, like import numpy as np. Why should we be different here?

Probably someone from this repo can jump in.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was added a long time ago in 31d721a - perhaps the style of back then? Can @landam remember?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is just some very old practice carried over. Just change that.

@petrasovaa petrasovaa modified the milestones: 8.4.0, 8.4.1 Apr 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GUI wxGUI related libraries module Python Related code is in Python raster Related to raster data processing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants